<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="edSHo" id="edSHo"><span data-lake-id="u08c6c30e" id="u08c6c30e">典型回答</span></h1>
  <p data-lake-id="u5f9e87d5" id="u5f9e87d5"><br></p>
  <p data-lake-id="u01e1a70e" id="u01e1a70e"><strong><span data-lake-id="u5dbb81ed" id="u5dbb81ed" style="color: rgb(47, 48, 52)">面向过程</span></strong><span data-lake-id="uf2b50688" id="uf2b50688" style="color: rgb(47, 48, 52)">把问题分解成一个一个步骤，每个步骤用函数实现，依次调用即可。</span></p>
  <p data-lake-id="u2ee6a76c" id="u2ee6a76c"><span data-lake-id="u59138104" id="u59138104" style="color: rgb(47, 48, 52)">​</span><br></p>
  <p data-lake-id="u17c9af25" id="u17c9af25"><span data-lake-id="uea476b4d" id="uea476b4d" style="color: rgb(47, 48, 52)">我们在进行面向过程编程的时候，不需要考虑那么多，上来先定义一个函数，然后使用各种诸如if-else、for-each等方式进行代码执行。最典型的用法就是实现一个简单的算法，比如实现冒泡排序。 </span></p>
  <p data-lake-id="u2f34bdc6" id="u2f34bdc6"><span data-lake-id="ub9b7e7ed" id="ub9b7e7ed" style="color: rgb(47, 48, 52)">​</span><br></p>
  <p data-lake-id="u62d2ca80" id="u62d2ca80"><strong><span data-lake-id="ub1e2067f" id="ub1e2067f" style="color: rgb(47, 48, 52)">面向对象</span></strong><span data-lake-id="ucc20c7ad" id="ucc20c7ad" style="color: rgb(47, 48, 52)">将问题分解成一个一个步骤，对每个步骤进行相应的抽象，形成对象，通过不同对象之间的调用，组合解决问题。</span></p>
  <p data-lake-id="u389fecc2" id="u389fecc2"><span data-lake-id="ucc9ea0f9" id="ucc9ea0f9" style="color: rgb(47, 48, 52)">​</span><br></p>
  <p data-lake-id="u7e1e4e7a" id="u7e1e4e7a"><span data-lake-id="u7156441d" id="u7156441d" style="color: rgb(47, 48, 52)">就是说，在进行面向对象进行编程的时候，要把属性、行为等封装成对象，然后基于这些对象及对象的能力进行业务逻辑的实现。比如想要造一辆车，上来要先把车的各种属性定义出来，然后抽象成一个Car类。</span></p>
  <p data-lake-id="ud9e5405e" id="ud9e5405e"><span data-lake-id="uc894c56e" id="uc894c56e" style="color: rgb(47, 48, 52)">​</span><br></p>
  <p data-lake-id="u58bc9e76" id="u58bc9e76"><span data-lake-id="ua5829b65" id="ua5829b65" style="color: rgb(47, 48, 52)">面向对象有封装、继承、多态三大基本特征，和单一职责原则、开放封闭原则、Liskov替换原则、依赖倒置原则和 接口隔离原则等五大基本原则。</span></p>
  <p data-lake-id="u073007e1" id="u073007e1"><span data-lake-id="u4d065de1" id="u4d065de1" style="color: rgb(47, 48, 52)">​</span><br></p>
  <h1 data-lake-id="tFAjo" id="tFAjo"><span data-lake-id="u7b6faf76" id="u7b6faf76" style="color: rgb(47, 48, 52)">知识扩展</span></h1>
  <h2 data-lake-id="wrTKk" id="wrTKk"><span data-lake-id="u063b53eb" id="u063b53eb" style="color: rgb(47, 48, 52)">面向对象的三大基本特征?</span></h2>
  <p data-lake-id="ud20eac61" id="ud20eac61"><br></p>
  <p data-lake-id="u28c013d0" id="u28c013d0"><span data-lake-id="u83afe9e1" id="u83afe9e1" style="color: rgb(47, 48, 52)">三大基本特征：封装、继承、多态。</span></p>
  <p data-lake-id="u747f9e0b" id="u747f9e0b"><span data-lake-id="uc5f0cbd5" id="uc5f0cbd5" style="color: rgb(47, 48, 52)">​</span><br></p>
  <h3 data-lake-id="UQ9ys" id="UQ9ys"><span data-lake-id="u8346ea4f" id="u8346ea4f" style="color: rgb(47, 48, 52)">封装</span></h3>
  <p data-lake-id="u09cff00f" id="u09cff00f"><span data-lake-id="u76d3cdb2" id="u76d3cdb2" class="lake-fontsize-11" style="color: rgb(38, 38, 38); background-color: rgb(245, 245, 249)">​</span><br></p>
  <p data-lake-id="ua3f9c5c1" id="ua3f9c5c1"><span data-lake-id="u519cdaa8" id="u519cdaa8">封装就是把现实世界中的客观事物抽象成一个Java类，然后在类中存放属性和方法。如封装一个</span><code data-lake-id="u8e84b679" id="u8e84b679"><span data-lake-id="u5408bd15" id="u5408bd15">汽车</span></code><span data-lake-id="uffdfcbaf" id="uffdfcbaf">类，其中包含了</span><code data-lake-id="u933eefdb" id="u933eefdb"><span data-lake-id="u25d6c15a" id="u25d6c15a">发动机</span></code><span data-lake-id="ucd510f48" id="ucd510f48">、</span><code data-lake-id="u78706133" id="u78706133"><span data-lake-id="ubef90917" id="ubef90917">轮胎</span></code><span data-lake-id="u27c364e2" id="u27c364e2"> 、</span><code data-lake-id="ue39c7003" id="ue39c7003"><span data-lake-id="u3805b13a" id="u3805b13a">底盘</span></code><span data-lake-id="u8e1f6d2e" id="u8e1f6d2e">等属性，并且有</span><code data-lake-id="u3f1ed3fb" id="u3f1ed3fb"><span data-lake-id="u740af994" id="u740af994">启动</span></code><span data-lake-id="uf6131e72" id="uf6131e72">、</span><code data-lake-id="ue20c9bc3" id="ue20c9bc3"><span data-lake-id="u65dc453b" id="u65dc453b">前进</span></code><span data-lake-id="ua5ff6048" id="ua5ff6048">等方法。</span></p>
  <p data-lake-id="u933c57fe" id="u933c57fe"><span data-lake-id="u14d19ba1" id="u14d19ba1">​</span><br></p>
  <h3 data-lake-id="DfscL" id="DfscL"><span data-lake-id="u5f125e21" id="u5f125e21">继承</span></h3>
  <p data-lake-id="u1b155601" id="u1b155601"><span data-lake-id="ub0832cb9" id="ub0832cb9">像现实世界中儿子可以继承父亲的财产、样貌、行为等一样，编程世界中也有继承，继承的主要目的就是为了复用。子类可以继承父类，这样就可以把父类的属性和方法继承过来。</span></p>
  <p data-lake-id="u46525302" id="u46525302"><span data-lake-id="u5c3681ba" id="u5c3681ba">​</span><br></p>
  <p data-lake-id="ud0a9dec2" id="ud0a9dec2"><span data-lake-id="u8720d5b6" id="u8720d5b6">如Dog类可以继承Animal类，继承过来</span><code data-lake-id="u6b07cf85" id="u6b07cf85"><span data-lake-id="uc689288f" id="uc689288f">嘴巴</span></code><span data-lake-id="u71619b2d" id="u71619b2d">、</span><code data-lake-id="u8c991410" id="u8c991410"><span data-lake-id="ua3c94c3b" id="ua3c94c3b">颜色</span></code><span data-lake-id="uf6715847" id="uf6715847">等属性， </span><code data-lake-id="ud2e9a340" id="ud2e9a340"><span data-lake-id="ue24e8e07" id="ue24e8e07">吃东西</span></code><span data-lake-id="u2b58395c" id="u2b58395c">、</span><code data-lake-id="u740f0597" id="u740f0597"><span data-lake-id="uecd5a22f" id="uecd5a22f">奔跑</span></code><span data-lake-id="u2b091b1a" id="u2b091b1a">等行为。</span></p>
  <p data-lake-id="ua39ffea4" id="ua39ffea4"><span data-lake-id="ub5717b99" id="ub5717b99">​</span><br></p>
  <h3 data-lake-id="ugHMp" id="ugHMp"><span data-lake-id="u76b77804" id="u76b77804">多态</span></h3>
  <p data-lake-id="u73a1acba" id="u73a1acba"><br></p>
  <p data-lake-id="uc4b6a4b3" id="uc4b6a4b3"><span data-lake-id="u7fa5a549" id="u7fa5a549" style="color: rgb(18, 18, 18)">多态是指在父类中定义的方法被子类继承之后，可以通过重写，使得父类和子类具有不同的实现，这使得同一个方法在父类及其各个子类中具有不同含义。</span></p>
  <p data-lake-id="u09e40ceb" id="u09e40ceb"><br></p>
  <p data-lake-id="u765ee153" id="u765ee153"><br></p>
  <h2 data-lake-id="XfMWw" id="XfMWw"><span data-lake-id="ufaa26c56" id="ufaa26c56">继承和实现</span></h2>
  <p data-lake-id="ua4974970" id="ua4974970"><br></p>
  <p data-lake-id="u0e745c9d" id="u0e745c9d"><span data-lake-id="u58037b1b" id="u58037b1b">在Java中，接口可以继承接口，抽象类可以实现接口，抽象类也可以继承具体类。普通类可以实现接口，普通类也可以继承抽象类和普通类。</span></p>
  <p data-lake-id="u395822f9" id="u395822f9"><span data-lake-id="u0e9713f4" id="u0e9713f4">​</span><br></p>
  <p data-lake-id="u13c8dcff" id="u13c8dcff"><span data-lake-id="u37e29f73" id="u37e29f73">Java支持多实现，但是只支持单继承。即一个类可以实现多个接口，但是不能继承多个类。</span></p>
  <p data-lake-id="u4bf54529" id="u4bf54529"><span data-lake-id="ub99f9a4e" id="ub99f9a4e">​</span><br></p>
  <h3 data-lake-id="fXUsz" id="fXUsz"><span data-lake-id="u5a62b53c" id="u5a62b53c">为什么Java不支持多继承？</span></h3>
  <p data-lake-id="u48570647" id="u48570647" style="text-align: justify"><br></p>
  <p data-lake-id="u361d0db2" id="u361d0db2"><span data-lake-id="uc4c5e0d5" id="uc4c5e0d5">​</span><br></p>
  <h2 data-lake-id="II5Ef" id="II5Ef"><span data-lake-id="u17b2aeab" id="u17b2aeab" style="color: rgb(47, 48, 52)">面向对象的五大基本原则？ </span></h2>
  <p data-lake-id="ue7317c50" id="ue7317c50"><br></p>
  <ul list="u563af8c1">
   <li fid="uc35f795a" data-lake-id="u189eb082" id="u189eb082" data-lake-index-type="true"><strong><span data-lake-id="u566d1941" id="u566d1941">单一职责原则（Single-Responsibility Principle</span></strong><span data-lake-id="uf1fe595d" id="uf1fe595d">）</span></li>
  </ul>
  <ul list="u563af8c1" data-lake-indent="1">
   <li fid="uc35f795a" data-lake-id="u5d7f9dd9" id="u5d7f9dd9" data-lake-index-type="true"><span data-lake-id="u8e0eca12" id="u8e0eca12">内容：一个类最好只做一件事</span></li>
   <li fid="uc35f795a" data-lake-id="uea3240be" id="uea3240be" data-lake-index-type="true"><strong><span data-lake-id="uaa91876f" id="uaa91876f">提高可维护性</span></strong><span data-lake-id="uafe20dca" id="uafe20dca">：当一个类只负责一个功能时，其实现通常更简单、更直接，这使得理解和维护变得更容易。</span></li>
   <li fid="uc35f795a" data-lake-id="u8ec06a60" id="u8ec06a60" data-lake-index-type="true"><strong><span data-lake-id="u408e4873" id="u408e4873">减少代码修改的影响</span></strong><span data-lake-id="ue3575d78" id="ue3575d78">：更改影响较小的部分，因此减少了对系统其他部分的潜在破坏。</span></li>
  </ul>
  <ul list="u563af8c1" start="2">
   <li fid="uc35f795a" data-lake-id="u374dd428" id="u374dd428" data-lake-index-type="true"><strong><span data-lake-id="ueb1be4ba" id="ueb1be4ba">开放封闭原则（Open-Closed principle）</span></strong></li>
  </ul>
  <ul list="u563af8c1" data-lake-indent="1">
   <li fid="uc35f795a" data-lake-id="u41f55de8" id="u41f55de8" data-lake-index-type="true"><span data-lake-id="ua5ba4bc6" id="ua5ba4bc6">内容：对扩展开放、对修改封闭</span></li>
   <li fid="uc35f795a" data-lake-id="u4799b62f" id="u4799b62f" data-lake-index-type="true"><strong><span data-lake-id="u94ee87d6" id="u94ee87d6">促进可扩展性</span></strong><span data-lake-id="ub6a1c8ee" id="ub6a1c8ee">：可以在不修改现有代码的情况下扩展功能，这意味着新的功能可以添加，而不会影响旧的功能。</span></li>
   <li fid="uc35f795a" data-lake-id="u57fd547b" id="u57fd547b" data-lake-index-type="true"><strong><span data-lake-id="u772c7d18" id="u772c7d18">降低风险</span></strong><span data-lake-id="uc6fbcb70" id="uc6fbcb70">：由于不需要修改现有代码，因此引入新错误的风险较低。</span></li>
  </ul>
  <ul list="u563af8c1" start="3">
   <li fid="uc35f795a" data-lake-id="u0b105725" id="u0b105725" data-lake-index-type="true"><strong><span data-lake-id="u34a8c07c" id="u34a8c07c">Liskov替换原则（Liskov-Substituion Principle）</span></strong></li>
  </ul>
  <ul list="u563af8c1" data-lake-indent="1">
   <li fid="uc35f795a" data-lake-id="u1edfb1b8" id="u1edfb1b8" data-lake-index-type="true"><span data-lake-id="u1dc5c4d3" id="u1dc5c4d3">内容：子类必须能够替换其基类</span></li>
   <li fid="uc35f795a" data-lake-id="u012ea42a" id="u012ea42a" data-lake-index-type="true"><strong><span data-lake-id="u05089e6d" id="u05089e6d">提高代码的可互换性</span></strong><span data-lake-id="u6f19590a" id="u6f19590a">：能够用派生类的实例替换基类的实例，使得代码更加模块化，提高了其灵活性。</span></li>
   <li fid="uc35f795a" data-lake-id="uc13e0cc2" id="uc13e0cc2" data-lake-index-type="true"><strong><span data-lake-id="ufe8fefa4" id="ufe8fefa4">增加代码的可重用性</span></strong><span data-lake-id="u4d6bb4b5" id="u4d6bb4b5">：遵循LSP的类和组件更容易被重用于不同的上下文。</span></li>
  </ul>
  <ul list="u563af8c1" start="4">
   <li fid="uc35f795a" data-lake-id="ua1484776" id="ua1484776" data-lake-index-type="true"><strong><span data-lake-id="u647ab296" id="u647ab296">依赖倒置原则（Dependency-Inversion Principle）</span></strong></li>
  </ul>
  <ul list="u563af8c1" data-lake-indent="1">
   <li fid="uc35f795a" data-lake-id="ube65de2c" id="ube65de2c" data-lake-index-type="true"><span data-lake-id="u9288c9f6" id="u9288c9f6">内容：</span><span data-lake-id="u9e1077be" id="u9e1077be">程序要依赖于抽象接口，而不是具体的实现</span></li>
   <li fid="uc35f795a" data-lake-id="ubfd6a298" id="ubfd6a298" data-lake-index-type="true"><strong><span data-lake-id="u64ea6313" id="u64ea6313">提高代码的可测试性</span></strong><span data-lake-id="u1b6d2731" id="u1b6d2731">：通过依赖于抽象而不是具体实现，可以轻松地对代码进行单元测试。</span></li>
   <li fid="uc35f795a" data-lake-id="u9a42d3d4" id="u9a42d3d4" data-lake-index-type="true"><strong><span data-lake-id="ua65f117d" id="ua65f117d">减少系统耦合</span></strong><span data-lake-id="u1c3bc8ab" id="u1c3bc8ab">：系统的高层模块不依赖于低层模块的具体实现，从而使得系统更加灵活和可维护。</span></li>
  </ul>
  <ul list="u563af8c1" start="5">
   <li fid="uc35f795a" data-lake-id="u60030389" id="u60030389" data-lake-index-type="true"><strong><span data-lake-id="uc531bba2" id="uc531bba2">接口隔离原则（Interface-Segregation Principle）。</span></strong></li>
  </ul>
  <ul list="u563af8c1" data-lake-indent="1">
   <li fid="uc35f795a" data-lake-id="u9b2e9bff" id="u9b2e9bff" data-lake-index-type="true"><span data-lake-id="u0629ffae" id="u0629ffae">内容：使用多个小的专门的接口，而不要使用一个大的总接口</span></li>
   <li fid="uc35f795a" data-lake-id="ub79727bb" id="ub79727bb" data-lake-index-type="true"><strong><span data-lake-id="u5cdb5897" id="u5cdb5897">减少系统耦合</span></strong><span data-lake-id="u97503978" id="u97503978">：通过使用专门的接口而不是一个大而全的接口，系统中的不同部分之间的依赖性减少了。</span></li>
   <li fid="uc35f795a" data-lake-id="u02589cb5" id="u02589cb5" data-lake-index-type="true"><strong><span data-lake-id="u2bb83ac1" id="u2bb83ac1">提升灵活性和稳定性</span></strong><span data-lake-id="u01f21993" id="u01f21993">：更改一个小接口比更改一个大接口风险更低，更容易管理。</span></li>
  </ul>
  <p data-lake-id="u38ea9db4" id="u38ea9db4"><span data-lake-id="uba04eef5" id="uba04eef5" style="color: rgb(47, 48, 52)">​</span><br></p>
  <p data-lake-id="u1fd347d2" id="u1fd347d2"><span data-lake-id="u93bb8d89" id="u93bb8d89" style="color: rgb(47, 48, 52)">以下是一些示例，通过代码的方式给大家介绍一下这几个原则具体的应用和实践。</span></p>
  <h4 data-lake-id="z4dyG" id="z4dyG"><span data-lake-id="u5eaafa3e" id="u5eaafa3e" style="color: rgb(47, 48, 52)">单一职责原则：</span><span data-lake-id="uc2b21d0b" id="uc2b21d0b" class="lake-fontsize-12">一个类最好只做一件事</span></h4>
  <p data-lake-id="uaa641a40" id="uaa641a40"><br></p>
  <p data-lake-id="u39a18b56" id="u39a18b56"><span data-lake-id="u1acb551f" id="u1acb551f">假如有一个类用于日志消息的处理，但是这个类不仅仅负责创建日志消息，还负责将其写入文件。根据单一职责原则，我们应该将这两个职责分开，让一个类专注于创建日志消息，而另一个类专注于日志消息的存储。</span></p>
  <p data-lake-id="u9fece140" id="u9fece140"><span data-lake-id="ubc7d718e" id="ubc7d718e">​</span><br></p>
  <pre lang="java"><code>
// 负责日志消息的创建
class LogMessageCreator {
    public String createLogMessage(String message, LogLevel level) {
        // 创建和格式化日志消息
        LocalDateTime now = LocalDateTime.now();
        return now.toString() + " [" + level.toString() + "] " + message;
    }
}

// 日志级别枚举
enum LogLevel {
    INFO, WARNING, ERROR;
}

// 负责日志消息的存储
class LogFileWriter {
    public void writeToFile(String message, String filename) {
        // 将日志消息写入指定的文件
        try {
            Files.write(Paths.get(filename), message.getBytes(), StandardOpenOption.APPEND);
        } catch (IOException e) {
            // 处理文件写入异常
        }
    }
}

// 使用例子
public class Logger {
    private LogMessageCreator messageCreator;
    private LogFileWriter fileWriter;

    public Logger() {
        messageCreator = new LogMessageCreator();
        fileWriter = new LogFileWriter();
    }

    public void log(String message, LogLevel level, String filename) {
        String logMessage = messageCreator.createLogMessage(message, level);
        fileWriter.writeToFile(logMessage, filename);
    }
}

</code></pre>
  <p data-lake-id="u70635a6e" id="u70635a6e"><br></p>
  <p data-lake-id="u3dd7fb68" id="u3dd7fb68"><span data-lake-id="u168295b1" id="u168295b1">LogMessageCreator类只负责创建和格式化日志消息，而LogFileWriter类只负责将日志消息写入文件。这种分离确保了每个类只有一个改变的原因，遵循了单一职责原则。</span></p>
  <p data-lake-id="u74b80465" id="u74b80465"><span data-lake-id="u265d075d" id="u265d075d">​</span><br></p>
  <h4 data-lake-id="Hj0CM" id="Hj0CM"><span data-lake-id="u18f3f370" id="u18f3f370">开放封闭原则：对扩展开放、对修改封闭</span></h4>
  <p data-lake-id="u5657d1ea" id="u5657d1ea"><br></p>
  <p data-lake-id="u3179ae67" id="u3179ae67"><span data-lake-id="u96f27f64" id="u96f27f64">假设有一个图形绘制应用程序，其中有一个Shape类。</span></p>
  <p data-lake-id="u3c7c85da" id="u3c7c85da"><span data-lake-id="u84baccc0" id="u84baccc0">​</span><br></p>
  <p data-lake-id="u3f42c65c" id="u3f42c65c"><span data-lake-id="ufdc78767" id="ufdc78767">在遵守开闭原则的情况下，如果要添加新的形状类型，应该能够扩展Shape类而无需修改现有代码。这可以通过创建继承自Shape的新类来实现，如Circle和Rectangle。</span></p>
  <p data-lake-id="u1e7b43ab" id="u1e7b43ab"><span data-lake-id="u10654038" id="u10654038">​</span><br></p>
  <pre lang="java"><code>
// 形状接口
interface Shape {
    void draw();
}

// 圆形类
class Circle implements Shape {
    public void draw() {
        // 绘制圆形
    }
}

// 矩形类
class Rectangle implements Shape {
    public void draw() {
        // 绘制矩形
    }
}

// 图形绘制类
class GraphicEditor {
    public void drawShape(Shape shape) {
        shape.draw();
    }
}

</code></pre>
  <p data-lake-id="ue82d7640" id="ue82d7640"><br></p>
  <p data-lake-id="u0120382f" id="u0120382f"><span data-lake-id="u96ff335d" id="u96ff335d">这样，当我们想要修改Circle的时候不会对Rectangle有任何影响。</span></p>
  <p data-lake-id="u8935f58e" id="u8935f58e"><br></p>
  <h4 data-lake-id="si3Aq" id="si3Aq"><span data-lake-id="ud4bc31b9" id="ud4bc31b9">里氏替换原则：</span><span data-lake-id="u20b7f0d2" id="u20b7f0d2" class="lake-fontsize-12">子类必须能够替换其基类</span></h4>
  <p data-lake-id="u557520d9" id="u557520d9"><br></p>
  <p data-lake-id="u169d0fc3" id="u169d0fc3"><span data-lake-id="ua89a8cf3" id="ua89a8cf3">假设有一个函数接受Bird对象作为参数。根据里氏替换原则，这个函数应该能够接受一个Bird的子类对象（如Sparrow或Penguin）而不影响程序运行。</span></p>
  <p data-lake-id="u65c3df26" id="u65c3df26"><span data-lake-id="uca639617" id="uca639617">​</span><br></p>
  <pre lang="java"><code>
// 鸟类
class Bird {
    public void fly() {
        // 实现飞行
    }
}

// 麻雀类
class Sparrow extends Bird {
    // 重写飞行行为
}

// 企鹅类
class Penguin extends Bird {
    @Override
    public void fly() {
        throw new UnsupportedOperationException("Penguin can't fly");
    }
}

// 使用鸟类的函数
public void makeItFly(Bird bird) {
    bird.fly();
}

</code></pre>
  <p data-lake-id="ua0637a24" id="ua0637a24"><br></p>
  <p data-lake-id="u5dd86aa4" id="u5dd86aa4"><span data-lake-id="u4cd0a287" id="u4cd0a287">我们可以把任意一个Bird的实现传入到makeItFly方法中，实现了用子类替换父类</span></p>
  <p data-lake-id="u71ba6cbe" id="u71ba6cbe"><br></p>
  <h4 data-lake-id="MYinr" id="MYinr"><span data-lake-id="u2fd7dad4" id="u2fd7dad4">依赖倒置原则：</span><span data-lake-id="ub2ad34a4" id="ub2ad34a4" class="lake-fontsize-12">程序要依赖于抽象接口，而不是具体的实现</span></h4>
  <p data-lake-id="ub9bee514" id="ub9bee514"><br></p>
  <p data-lake-id="u76ffc914" id="u76ffc914"><span data-lake-id="u0a46caf0" id="u0a46caf0">在构建一个电商应用程序时，一个高层的“订单处理”模块不应该直接依赖于一个低层的“数据访问”模块。相反，它们应该依赖于抽象，例如一个接口。这样，数据访问的具体实现可以随时改变，而不会影响订单处理模块。</span></p>
  <p data-lake-id="uf6f4980f" id="uf6f4980f"><span data-lake-id="u0536fbb0" id="u0536fbb0">​</span><br></p>
  <pre lang="java"><code>
// 数据访问接口
interface DataAccess {
    void saveOrder(Order order);
}

// 高层模块：订单处理
class OrderProcessingService {
    private DataAccess dataAccess;

    public OrderProcessingService(DataAccess dataAccess) {
        this.dataAccess = dataAccess;
    }

    public void processOrder(Order order) {
        // 订单处理逻辑
        dataAccess.saveOrder(order);
    }
}

// 低层模块：数据访问实现
class DatabaseDataAccess implements DataAccess {
    public void saveOrder(Order order) {
        // 数据库保存逻辑
    }
}

</code></pre>
  <p data-lake-id="ude82bca4" id="ude82bca4"><br></p>
  <p data-lake-id="uca3c46ec" id="uca3c46ec"><span data-lake-id="u01dd4464" id="u01dd4464">这样底层的数据存储我们就可以任意更换，可以用MySQL，可以用Redis，可以用达梦，也可以用OceanBase，因为我们做到了依赖接口，而不是具体实现。</span></p>
  <p data-lake-id="u70f5137d" id="u70f5137d"><br></p>
  <h4 data-lake-id="pFkEK" id="pFkEK"><span data-lake-id="u5284285c" id="u5284285c">接口隔离原则：使用多个小的专门的接口，而不要使用一个大的总接口</span></h4>
  <p data-lake-id="u3eef624e" id="u3eef624e"><br></p>
  <p data-lake-id="u8e45f5dd" id="u8e45f5dd"><span data-lake-id="u273d8f38" id="u273d8f38">如果有一个多功能打印机接口包含打印、扫描和复制功能，那么只需要打印功能的客户端应该不必实现扫描和复制的接口。这可以通过将大接口分解为更小且更具体的接口来实现。</span></p>
  <p data-lake-id="ua4d10663" id="ua4d10663"><span data-lake-id="u1dd7c84f" id="u1dd7c84f">​</span><br></p>
  <pre lang="java"><code>
// 打印接口
interface Printer {
    void print();
}

// 扫描接口
interface Scanner {
    void scan();
}

// 多功能打印机类
class MultiFunctionPrinter implements Printer, Scanner {
    public void print() {
        // 打印实现
    }

    public void scan() {
        // 扫描实现
    }
}

// 仅打印类
class SimplePrinter implements Printer {
    public void print() {
        // 打印实现
    }
}

</code></pre>
  <p data-lake-id="ue4db09d4" id="ue4db09d4"><br></p>
  <p data-lake-id="u83b8b168" id="u83b8b168"><br></p>
 </body>
</html>